using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace LabyrinthProject
{
    public class Quad
    {
        private Vector3 origin;
        private Plane plane;
        private float width;
        private float height;

        private Vector3 upperLeft;
        private Vector3 lowerLeft;
        private Vector3 upperRight;
        private Vector3 lowerRight;

        private Vector3 normal;
        private Vector3 up;
        private Vector3 left;

        private VertexBuffer vertexBuffer;
        private NormalMappedVertex[] vertices;



        public Vector3 Origin
        {
            get { return origin; }
            set { origin = value; }
        }

        public Plane Plane
        {
            get { return plane; }
            set { plane = value; }
        }
        public Vector3 UpperLeft
        {
            get { return upperLeft; }
            set { upperLeft = value; }
        }
        public Vector3 LowerLeft
        {
            get { return lowerLeft; }
            set { lowerLeft = value; }
        }
        public Vector3 UpperRight
        {
            get { return upperRight; }
            set { upperRight = value; }
        }
        public Vector3 LowerRight
        {
            get { return lowerRight; }
            set { lowerRight = value; }
        }

        public Vector3 Normal
        {
            get { return normal; }
            set { normal = value; }
        }
        public Vector3 Up
        {
            get { return up; }
            set { up = value; }
        }
        public Vector3 Left
        {
            get { return left; }
            set { left = value; }
        }

        public VertexBuffer VertexBuffer
        {
            get { return vertexBuffer; }
            set { vertexBuffer = value; }
        }
        public NormalMappedVertex[] Vertices
        {
            get { return vertices; }
            set { vertices = value; }
        }

        public float Width
        {
            get { return width; }
            set { width = value; }
        }
        public float Height
        {
            get { return height; }
            set { height = value; }
        }

        public Quad( Vector3 origin, Vector3 normal, Vector3 up, float width, float height )
        {
            Vertices = new NormalMappedVertex[6];

            this.origin = origin;
            this.normal = normal;
            this.up = up;
            this.left = Vector3.Cross(normal, up);
            this.width = width;
            this.height = height;

            // Calculate the quad corners
            Vector3 uppercenter = ( up * height ) + origin;
            upperLeft = uppercenter + ( left * width / 2 );
            upperRight = uppercenter - ( left * width / 2 );
            lowerLeft = upperLeft - ( up * height );
            lowerRight = upperRight - ( up * height );

            fillVertices();

            plane = new Plane(lowerLeft, lowerRight, upperLeft);
        }

        private void fillVertices()
        {
            // Fill in texture coordinates to display full texture
            // on quad
            Vector2 textureUpperLeft = new Vector2( 0.0f, 0.0f );
            Vector2 textureUpperRight = new Vector2( width / 2000, 0.0f );
            Vector2 textureLowerLeft = new Vector2( 0.0f, height / 2000 );
            Vector2 textureLowerRight = new Vector2( width / 2000, height / 2000 );

            // Provide a normal for each vertex
            for ( int i = 0 ; i < Vertices.Length ; i++ )
            {
                vertices[i].Normal = normal;
            }

            // Set the position and texture coordinate for each
            // vertex

            vertices[0].Position = lowerLeft;
            vertices[0].TexCoord = textureLowerLeft;

            vertices[1].Position = upperLeft;
            vertices[1].TexCoord = textureUpperLeft;

            vertices[2].Position = lowerRight;
            vertices[2].TexCoord = textureLowerRight;

            vertices[3].Position = lowerRight;
            vertices[3].TexCoord = textureLowerRight;

            vertices[4].Position = upperLeft;
            vertices[4].TexCoord = textureUpperLeft;

            vertices[5].Position = upperRight;
            vertices[5].TexCoord = textureUpperRight;

            Vector4 tangent;

            for ( int i = 0 ; i < 6 ; i += 3 )
            {
                NormalMappedVertex.CalcTangent(
                    ref vertices[i].Position,
                    ref vertices[i + 1].Position,
                    ref vertices[i + 2].Position,
                    ref vertices[i].TexCoord,
                    ref vertices[i + 1].TexCoord,
                    ref vertices[i + 2].TexCoord,
                    ref vertices[i].Normal,
                    out tangent );

                vertices[i].Tangent = tangent;
                vertices[i + 1].Tangent = tangent;
                vertices[i + 2].Tangent = tangent;
            }
        }
    }
}
